<?php
/**
 * Writes object to XML. XmlWriter has been tested with primitives, arrays,
 * associative arrays and objects.
 *
 * Usage: 
 * $data = new stdClass( );
 * $data->name = new stdClass( );
 * $data->name->first = 'John';
 * $data->name->last = 'Smith';
 * $data->email = array( 'john@smith.com', 'jsmith@acme.com' );
 * $data->misc = array();
 * $data->misc['dog'] = 'fido';
 * $data->misc['wife'] = 'Jane Smith';
 * $data->created = 1234567890;
 * 
 * $writer = new Rest_Util_XmlWriter();
 * echo $writer->getXML( $data );
 */
class Rest_Util_XmlWriter
{

    private $doc;

    //http://us3.php.net/manual/en/domdocument.savexml.php
    public function getXML ( $data = NULL, $rootTag = 'data' )
    {
        $data = new stdClass( );
        $data->name = new stdClass( );
        $data->name->first = 'John';
        $data->name->last = 'Smith';
        $data->misc = array();
        $data->misc['dog'] = 'fido';
        $data->misc['wife'] = 'Jane Smith';
        $data->email = array( 'john@smith.com', 'jsmith@acme.com' );
        $data->created = 1234567890;
        
        $this->doc = new DOMDocument( '1.0' );
        $this->doc->formatOutput = true;
        
        $root = $this->doc->createElement( $rootTag );
        $root = $this->doc->appendChild( $root );
        
        $this->_createElement( $data, $root );

        return $this->doc->saveXML();
    }

    private function _createElement ( $data, $parentElement )
    {
        foreach ( $data as $key => $value ) {
            // If value is indexed array, create an element with the
            // same tag name for each item
            if ( $this->is_array( $value ) ) {
                foreach ( $value as $key2 => $value2 ) {
                    $element = $this->doc->createElement( $key, strval( $value2 ) );
                    $parentElement->appendChild( $element );
                }
            } else {
                // If value is an object or associative array, create element
                // and then loop through its children using this same method
                if ( is_object( $value ) || is_array( $value ) ) {
                    $element = $this->doc->createElement( $key );
                    $this->_createElement( $value, $element );
                // If the element is a simple primitive then just creat the element
                } else {
                    $element = $this->doc->createElement( $key, strval( $value ) );
                }
                $parentElement->appendChild( $element );
            }
        }
    }

    private function is_array ( $array )
    { 
       if ( !is_array($array) || empty($array) ) {
          return false;
       }
       $next = 0;
       foreach ( $array as $k => $v ) {
          if ( $k !== $next ) return false;
          $next++;
       }
       return true;
    }
}
